package com.tinem.platform.web.auth.grant.client_credentials_user;

import cn.hutool.core.util.StrUtil;
import com.tinem.platform.module.pojo.vo.error.UserException;
import com.tinem.platform.module.starter.sdk.MessageCode;
import com.tinem.platform.module.starter.web.util.ServletUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author fengzhihao
 * @version v1
 * @program: platform
 * @className ClientCredentialsUserTokenGranter
 * @description TODO
 * @site
 * @company
 * @create 2021/12/22 16:42:13
 */
public class ClientCredentialsUserTokenGranter extends AbstractTokenGranter {
    // 仅仅复制了 ResourceOwnerPasswordTokenGranter，只是改变了 GRANT_TYPE 的值，来验证自定义授权模式的可行性
    public static final String GRANT_TYPE = "client_credentials_user";

    private final AuthenticationManager authenticationManager;

    public ClientCredentialsUserTokenGranter(
            AuthenticationManager authenticationManager,
            AuthorizationServerTokenServices tokenServices,
            ClientDetailsService clientDetailsService,
            OAuth2RequestFactory requestFactory) {
        this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
    }
    protected ClientCredentialsUserTokenGranter(
            AuthenticationManager authenticationManager,
            AuthorizationServerTokenServices tokenServices,
            ClientDetailsService clientDetailsService,
            OAuth2RequestFactory requestFactory,
            String grantType) {
        super(tokenServices, clientDetailsService, requestFactory, grantType);
        this.authenticationManager = authenticationManager;
    }
    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        // 获取参数
        String id = tokenRequest.getRequestParameters().get("id");
        if(StrUtil.isEmpty(id)){
            throw new UserException(MessageCode.ERROR_COMMONS_PARAMS,"id");
        }
        String ip = ServletUtil.getClientIp(((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest());
        Authentication userAuth = new ClientCredentialsUserAuthenticationToken(client.getClientId(),id,ip);
        userAuth = authenticationManager.authenticate(userAuth);

        OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
        return new OAuth2Authentication(storedOAuth2Request, userAuth);
    }
}
